package com.trailwalker.javafx.widget.dialog;

import com.trailwalker.JavaUtils.DateUtils.DateUtils;
import com.trailwalker.javafx.utils.image.ImageUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class JfxLoadingForm {

    private Stage primaryStage = null;
    private Stage loadingStage = null;
    private final Label lblLoading;
    private final VBox vbLoading;
    private final ProgressIndicator piLoading;
    private final Canvas canvas;

    public JfxLoadingForm(Stage primaryStage) {
        this.primaryStage = primaryStage;
        loadingStage = new Stage();

        //窗口设置
        loadingStage.initOwner(primaryStage);
        loadingStage.initStyle(StageStyle.TRANSPARENT);
        loadingStage.initModality(Modality.APPLICATION_MODAL);

        //进度条设置
        lblLoading = new Label("加载中");
        lblLoading.setFont(Font.font(20));
        lblLoading.setTextFill(Color.WHITE);
        piLoading = new ProgressIndicator(-1);
        piLoading.setStyle("-fx-accent:'#ffffff';");
        canvas = new Canvas();
        canvas.setWidth(250);
        canvas.setHeight(250);
        drawCanvas();

        vbLoading = new VBox();
        vbLoading.setSpacing(10);
        vbLoading.setBackground(new Background(new BackgroundFill(Paint.valueOf("#000000bb"), CornerRadii.EMPTY, Insets.EMPTY)));
        vbLoading.getChildren().addAll(canvas, lblLoading);
        vbLoading.setAlignment(Pos.CENTER);

        Scene scene = new Scene(vbLoading);
        scene.setFill(null);
        loadingStage.setScene(scene);
        loadingStage.setHeight(primaryStage.getHeight());
        loadingStage.setWidth(primaryStage.getWidth());
        loadingStage.setX(primaryStage.getX());
        loadingStage.setY(primaryStage.getY());

        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                drawCanvas();
            }
        }, 0, 50, TimeUnit.MILLISECONDS);
    }

    private void drawCanvas() {
        if (canvas != null) {
            double canvasWidth = canvas.getWidth();
            double canvasHeight = canvas.getHeight();
            double radius = canvasWidth < canvasHeight ? canvasWidth / 2 - 10 : canvasHeight / 2 - 10;
            double midX = canvasWidth / 2;
            double midY = canvasHeight / 2;

            //获取画笔
            GraphicsContext graphicsContext2D = canvas.getGraphicsContext2D();

            //清除画布
            graphicsContext2D.clearRect(0, 0, canvasWidth, canvasHeight);

            //画一个白色的圆
            graphicsContext2D.setStroke(Color.WHITE);
            graphicsContext2D.setLineWidth(6);
            graphicsContext2D.strokeOval(midX - radius, midY - radius, radius * 2, radius * 2);

            for (int i = 0; i < 12; i++) {
                if (i == 0 || i == 3 || i == 6 || i == 9) {
                    graphicsContext2D.setLineWidth(3);
                    graphicsContext2D.setFont(Font.font(20));
                    //画白色长线
                    graphicsContext2D.setStroke(Color.WHITE);
                    graphicsContext2D.strokeLine(midX, midY - radius, midX, midY - radius + 15);
                    String degree = String.valueOf(i);
                    double stringWidth = ImageUtils.getStringWidth(degree, Font.getDefault().getName(), 20);
                    //画文字
                    graphicsContext2D.setFill(Color.YELLOW);
                    graphicsContext2D.fillText(degree, midX - stringWidth / 2, midY - radius + 40);
                } else {
                    graphicsContext2D.setLineWidth(2);
                    graphicsContext2D.setFont(Font.font(13));
                    //画白色短线
                    graphicsContext2D.setStroke(Color.WHITE);
                    graphicsContext2D.strokeLine(midX, midY - radius, midX, midY - radius + 10);
                    String degree = String.valueOf(i);
                    double stringWidth = ImageUtils.getStringWidth(degree, Font.getDefault().getName(), 13);
                    //画文字
                    graphicsContext2D.fillText(degree, midX - stringWidth / 2, midY - radius + 25);
                    graphicsContext2D.setFill(Color.YELLOW);
                }
                graphicsContext2D.translate(midX, midY);
                graphicsContext2D.rotate(30);
                graphicsContext2D.translate(-1 * midX, -1 * midY);
            }

            //画布还原
            graphicsContext2D.setTransform(1, 0, 0, 1, 0, 0);

            Date date = new Date();
            double hour = Double.parseDouble(DateUtils.getHour(date));
            double minute = Double.parseDouble(DateUtils.getMinute(date));
            double milliSecondSecond = Double.parseDouble(DateUtils.getMilliSecond(date));
            double second = milliSecondSecond / 1000;

            double secondDegree = second * 6;
            double minuteDegree = second / 10 + minute * 6;
            double hourDegree = second / 120 + minute / 2 + hour * 30;

            //画3根指针
            graphicsContext2D.setLineWidth(6);
            //将坐标系平移到圆点
            graphicsContext2D.translate(midX, midY);
            //画时针
            graphicsContext2D.rotate(hourDegree);
            //坐标还原
            graphicsContext2D.translate(-1 * midX, -1 * midY);
            graphicsContext2D.setStroke(Color.GREEN);
            graphicsContext2D.strokeLine(midX, midY, midX, midY - radius + 80);

            //画布还原
            graphicsContext2D.setTransform(1, 0, 0, 1, 0, 0);

            graphicsContext2D.setLineWidth(4);
            //将坐标系平移到圆点
            graphicsContext2D.translate(midX, midY);
            //画分针
            graphicsContext2D.rotate(minuteDegree);
            //坐标还原
            graphicsContext2D.translate(-1 * midX, -1 * midY);
            graphicsContext2D.setStroke(Color.BLUE);
            graphicsContext2D.strokeLine(midX, midY, midX, midY - radius + 60);

            //画布还原
            graphicsContext2D.setTransform(1, 0, 0, 1, 0, 0);

            graphicsContext2D.setLineWidth(2);
            //将坐标系平移到圆点
            graphicsContext2D.translate(midX, midY);
            //画秒针
            graphicsContext2D.rotate(secondDegree);
            //坐标还原
            graphicsContext2D.translate(-1 * midX, -1 * midY);
            graphicsContext2D.setStroke(Color.RED);
            graphicsContext2D.strokeLine(midX, midY, midX, midY - radius + 50);

            graphicsContext2D.setFill(Color.RED);
            graphicsContext2D.fillOval(midX - 5, midY - radius - 5, 10, 10);

            //画布还原
            graphicsContext2D.setTransform(1, 0, 0, 1, 0, 0);
        }
    }

    public JfxLoadingForm setSpacing(double value) {
        vbLoading.setSpacing(value);
        return this;
    }

    public JfxLoadingForm setText(String value) {
        lblLoading.setText(value);
        return this;
    }

    public JfxLoadingForm setFont(Font value) {
        lblLoading.setFont(value);
        return this;
    }

    public JfxLoadingForm setTextFill(Paint value) {
        lblLoading.setTextFill(value);
        return this;
    }

    public JfxLoadingForm setProgressIndicatorBackground(String value) {
        String background = "-fx-accent:'" + value + "';";
        piLoading.setStyle(background);
        return this;
    }

    public JfxLoadingForm setProgressIndicatorSize(double value) {
        piLoading.setPrefHeight(value);
        piLoading.setPrefWidth(value);
        return this;
    }

    public void show() {
        loadingStage.show();
    }

    public void close() {
        loadingStage.close();
    }
}
